package com.xjrh.traintravel.collector.netty.handler;

import java.util.ArrayList;
import java.util.List;
import com.xjrh.traintravel.collector.common.CRC16M;
import com.xjrh.traintravel.collector.common.CodeConvertor;
import com.xjrh.traintravel.collector.common.ResultData;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementCommandEnum;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementConstant;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementStructure;
import com.xjrh.traintravel.collector.netty.command.front.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 前置-指令处理类
 * @author snps
 * @create 2022-02-07 10:54
 * @describe
 **/
@Service
@Slf4j
public class FrontHandler extends BaseAgreementHandler {


    /**
     * 创建命令：前置版本信息获取
     * @param equipmentId 设备标识
     * @param commonNo 子命令编号
     * @return AgreementStructure
     */
    public AgreementStructure buildCommand(String equipmentId, String commonNo) {
        AgreementStructure agreement = new AgreementStructure();

        // 前导码(4)
        agreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        agreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        agreement.setFc(AgreementCommandEnum.S_06.getValue());
        // MAC地址(6)
        agreement.setAddr(equipmentId);
        // 序号(1)
        // agreement.setSeq(CodeConvertor.intToHexString(1, 1));
        agreement.setSeq(super.getEquipmentSeq(agreement.getAddr()));
        // 长度(2)
        agreement.setLen(CodeConvertor.intToHexString(1, 2));
        // 数据(N)
        agreement.setData(commonNo);
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(agreement);
        agreement.setFcs(crcValue);
        // 帧尾(1)
        agreement.setFs(AgreementConstant.FS_VALUE);

        return agreement;
    }

    /**
     * 发送获取信息命令
     * @param agreement 命令
     * @return ResultData
     */
    public ResultData sendGetInfoCommand(AgreementStructure agreement) {
        /* 发送命令 */
        super.sendCommand(agreement);

        ResultData result = new ResultData(Boolean.TRUE);
        result.setResult(Boolean.TRUE);
        result.setInfo("发送指令成功！");
        result.setData(null);
        return result;
    }

    /**
     * 得到 前置版本信息 响应数据
     *
     * @param equipmentId 设备标识
     * @param applyData 响应数据
     * @return FrontApplyData
     */
    public FrontData getFrontInfoApplyData(String equipmentId, String applyData) {
        int startIndex = 0, endIndex = 2;

        FrontData frontApplyData = new FrontData();
        frontApplyData.setEquipmentId(equipmentId);
        frontApplyData.setCommonNo(applyData.substring(startIndex, endIndex));
        startIndex=endIndex; endIndex+=2;
        frontApplyData.setFrontNum(Integer.parseInt(applyData.substring(startIndex, endIndex), 16));
        startIndex=endIndex; endIndex+=2;

        // 根据前置个数，创建对应的前置信息对象
        List<FrontInfo> lstFront = new ArrayList<>(frontApplyData.getFrontNum());
        int v1, v2;
        for (int i=0; i<frontApplyData.getFrontNum(); i++) {
            FrontInfo frontInfo = new FrontInfo();
            frontInfo.setCom(Integer.parseInt(applyData.substring(startIndex, endIndex), 16));
            startIndex=endIndex; endIndex+=2;
            frontInfo.setType(Integer.parseInt(applyData.substring(startIndex, endIndex), 16));
            startIndex=endIndex; endIndex+=12;
            frontInfo.setNo(applyData.substring(startIndex, endIndex));
            startIndex=endIndex; endIndex+=2;
            v1 = Integer.parseInt(applyData.substring(startIndex, endIndex), 16);
            startIndex=endIndex; endIndex+=2;
            v2 = Integer.parseInt(applyData.substring(startIndex, endIndex), 16);
            startIndex=endIndex; endIndex+=2;
            frontInfo.setSoftwareVersion(v1 + "." + v2);
            v1 = Integer.parseInt(applyData.substring(startIndex, endIndex), 16);
            startIndex=endIndex; endIndex+=2;
            v2 = Integer.parseInt(applyData.substring(startIndex, endIndex), 16);
            startIndex=endIndex; endIndex+=2;
            frontInfo.setHardwareVersion(v1 + "." + v2);

            lstFront.add(frontInfo);
        }
        frontApplyData.setFrontInfos(lstFront);
        return frontApplyData;
    }

    /**
     * 得到 DSP版本信息 响应数据
     *
     * @param equipmentId 设备标识
     * @param applyData 响应数据
     * @return DspData
     */
    public DspData getDspInfoApplyData(String equipmentId, String applyData) {
        DspData dspData = new DspData();
        dspData.setEquipmentId(equipmentId);
        dspData.setCommonNo(applyData.substring(0, 2));
        int v1, v2;
        v1 = Integer.parseInt(applyData.substring(2, 4), 16);
        v2 = Integer.parseInt(applyData.substring(4, 6), 16);
        dspData.setSoftwareVersion(v1 + "." + v2);
        v1 = Integer.parseInt(applyData.substring(6, 8), 16);
        v2 = Integer.parseInt(applyData.substring(8, 10), 16);
        dspData.setHardwareVersion(v1 + "." + v2);
        return dspData;
    }

    /**
     * 得到 软件版本 响应数据
     * @param equipmentId 设备标识
     * @param applyData 响应数据
     * @return VersionData
     */
    public VersionData getVersionApplyData(String equipmentId, String applyData) {
        VersionData versionData = new VersionData();
        versionData.setEquipmentId(equipmentId);
        versionData.setCommonNo(applyData.substring(0, 2));

        int v;

        // 软件版本
        StringBuilder sbuSoftVersion = new StringBuilder();
        sbuSoftVersion.append(Integer.parseInt(applyData.substring(2, 4), 16));
        sbuSoftVersion.append(".");
        v = Integer.parseInt(applyData.substring(4, 6), 16);
        sbuSoftVersion.append(v >= 10 ? v : "0"+v);
        sbuSoftVersion.append(".");
        v = Integer.parseInt(applyData.substring(6, 8), 16);
        sbuSoftVersion.append(v >= 10 ? v : "0"+v);
        sbuSoftVersion.append("-");
        v = Integer.parseInt(applyData.substring(8, 10), 16);
        sbuSoftVersion.append(v >= 10 ? v : "0"+v);
        v = Integer.parseInt(applyData.substring(10, 12), 16);
        sbuSoftVersion.append(v >= 10 ? v : "0"+v);
        v = Integer.parseInt(applyData.substring(12, 14), 16);
        sbuSoftVersion.append(v >= 10 ? v : "0"+v);
        v = Integer.parseInt(applyData.substring(14, 16), 16);
        sbuSoftVersion.append(v >= 10 ? v : "0"+v);
        sbuSoftVersion.append("-");
        v = Integer.parseInt(applyData.substring(16, 18), 16);
        sbuSoftVersion.append(v >= 10 ? v : "0"+v);
        versionData.setSoftwareVersion(sbuSoftVersion.toString());

        // 硬件版本
        StringBuilder hardSoftVersion = new StringBuilder();
        hardSoftVersion.append(Integer.parseInt(applyData.substring(18, 20), 16));
        hardSoftVersion.append(".");
        v = Integer.parseInt(applyData.substring(20, 22), 16);
        hardSoftVersion.append(v >= 10 ? v : "0"+v);
        hardSoftVersion.append(".");
        v = Integer.parseInt(applyData.substring(22, 24), 16);
        hardSoftVersion.append(v >= 10 ? v : "0"+v);
        versionData.setHardwareVersion(hardSoftVersion.toString());
        return versionData;
    }


    /**
     * 发送命令：前置数据透传
     *
     * @param data
     */
    public void sendTransmitData(TransmitData data) {
        /* 构造 协议内容 */
        StringBuilder sbuHexData = new StringBuilder();
        sbuHexData.append("01");
        sbuHexData.append(CodeConvertor.intToHexString(data.getCom(), 1));
        sbuHexData.append(CodeConvertor.intToHexString(data.getFrontType(), 1));
        sbuHexData.append(CodeConvertor.intToHexString(data.getData().length(), 2));
        sbuHexData.append(CodeConvertor.string2HexString(data.getData()));

        /* 构造 协议 */
        AgreementStructure agreement = new AgreementStructure();
        // 前导码(4)
        agreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        agreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        agreement.setFc(AgreementCommandEnum.S_OC.getValue());
        // MAC地址(6)
        agreement.setAddr(data.getEquipmentId());
        // 序号(1)
        agreement.setSeq(CodeConvertor.intToHexString(1, 1));
        // 长度(2)
        agreement.setLen(CodeConvertor.intToHexString(data.getData().length(), 2));
        // 数据(N)
        agreement.setData(sbuHexData.toString());
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(agreement);
        agreement.setFcs(crcValue);
        // 帧尾(1)
        agreement.setFs(AgreementConstant.FS_VALUE);

        /* 发送命令 */
        super.sendCommand(agreement);
    }

    /**
     * 收到回复：透传命令返回数据
     *
     * @param equipmentId
     * @param applyData
     * @return
     */
    public TransmitData getTransmitDataApply(String equipmentId, String applyData) {
        TransmitData transmitData = new TransmitData();
        transmitData.setEquipmentId(equipmentId);
        transmitData.setCommonNo(applyData.substring(0, 2));
        transmitData.setCom(Integer.parseInt(applyData.substring(2, 4), 16));
        transmitData.setFrontType(Integer.parseInt(applyData.substring(4, 6), 16));
        transmitData.setDataLength(Integer.parseInt(applyData.substring(6, 10), 16));
        transmitData.setData(CodeConvertor.hexString2String(applyData.substring(10)));
        return transmitData;
    }

}